package cn.shadow.beans;

import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

/**
 * Bean的定义
 * 我要定义的的这个Bean他的类型是什么
 * 他的构造方法是什么
 * 静态工厂模式
 * 工厂模式
 * @author 冯啸迪
 */
public interface BeanDefinition {

    String SCOPE_SINGLETON = "singleton";

    String SCOPE_PROTOTYPE = "prototype";

    /**
     * 当前BeanName是否是主键
     * @return 主键标识
     */
    boolean isPrimary();

    /**
     * 是不是单例模式
     * @return 结果
     */
    boolean isSingleton();

    /**
     * 是不是原型模式
     * @return 结果
     */
    boolean isPrototype();

    /**
     * 返回当前的空间类型
     * @return
     */
    String getScope();

    /**
     * 获取Bean的初始化方法
     * @return 返回方法名称
     */
    String getInitMethodName();

    /**
     * 获取Bean的销毁方法
     * @return 返回方法名称
     */
    String getDestroyMethodName();

    /**
     * 获取构造参数需要的类型
     * @return 返回参数类型列表
     */
    List<?> getConstructorArgumentValues();

    /**
     * 获取Bean的Class
     * @return 返回被定义类的Class
     */
    Class<?> getBeanClass();

    /**
     * 工厂模式的话工厂对象名称是什么
     * @return 返回工厂名称
     */
    String getFactoryBeanName();

    /**
     * 静态工厂模式
     * @return 静态工厂方法
     */
    String getFactoryMethodName();

    /**
     * 获取Method
     * @return 结果
     */
    Method getFactoryMethod();

    /**
     * 设置工厂方法，缓存使用
     * @param factoryMethod
     */
    void setFactoryMethod(Method factoryMethod);

    /**
     * 获取需要被注入的参数
     * @return 结果
     */
    List<PropertyValue> getPropertyValues();

    /**
     * 获取构造函数
     * @return 构造函数
     */
    Constructor<?> getConstructor();

    /**
     * 设置构造函数
     * @param constructor 搞糟函数
     */
    void setConstructor(Constructor<?> constructor);

    /**
     * 对Bean定义做一个基本的校验，单个关键的值至少不能为空
     * @return
     */
    default boolean validate(){
        if (getBeanClass() == null){
            if (StringUtils.isBlank(getFactoryBeanName()) || StringUtils.isBlank(getFactoryMethodName())){
                return false;
            }
        }
        if (getBeanClass() != null && StringUtils.isNotBlank(getFactoryBeanName())){
            return false;
        }
        return true;
    }

}
